package com.oss.service;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import javax.jdo.JDOObjectNotFoundException;
import javax.jdo.PersistenceManager;
import javax.jdo.Query;

import com.oss.PMF;
import com.oss.model.Project;

/**
 * @author xueqiang.mi
 * @date 2010-2-2
 */
public class ProjectService extends BaseService {

	public void add(Project prj) {
		PersistenceManager pm = PMF.get();
		try {
			// 根据名称生成ID
			prj.setId(generateId(prj.getName()));

			if (!isExist(prj.getId())) {
				pm.makePersistent(prj);
			}
		} finally {
			pm.close();
		}
	}

	public String delete(String id) {
		PersistenceManager pm = PMF.get();
		try {
			Project prj = pm.getObjectById(Project.class, id);
			String tagId = prj.getTag();
			pm.deletePersistent(prj);
			return tagId;
		} finally {
			pm.close();
		}
	}

	public Project get(String id) {
		PersistenceManager pm = PMF.get();
		try {
			Project prj = pm.getObjectById(Project.class, id);
			return prj;
		} catch (JDOObjectNotFoundException e) {
			return null;
		} finally {
			pm.close();
		}
	}

	@SuppressWarnings("unchecked")
	public List<Project> getHiddenProjects(long pageIndex, long pageSize) {
		PersistenceManager pm = PMF.get();
		try {
			Query query = pm.newQuery(Project.class, "enabled == false or frozen == true");
			query.setOrdering("createdDate desc");
			query.setRange((pageIndex - 1) * pageSize, pageIndex * pageSize);
			Collection<Project> c = pm.detachCopyAll((Collection<Project>) query.execute());
			return new ArrayList<Project>(c);
		} finally {
			pm.close();
		}
	}

	@SuppressWarnings("unchecked")
	public List<Project> getInvalidPrjsBySource(String source) {
		PersistenceManager pm = PMF.get();
		try {
			Query query = pm.newQuery(Project.class, "source == :source && enabled == false");
			query.setOrdering("name");
			Collection<Project> c = pm.detachCopyAll((Collection<Project>) query.execute(source));
			return new ArrayList<Project>(c);
		} finally {
			pm.close();
		}
	}

	@SuppressWarnings("unchecked")
	public List<Project> getLatestPrjs(long pageIndex, long pageSize) {
		PersistenceManager pm = PMF.get();
		try {
			Query query = pm.newQuery(Project.class, "enabled == true");
			query.setOrdering("createdDate desc");
			query.setRange((pageIndex - 1) * pageSize, pageIndex * pageSize);
			Collection<Project> c = pm.detachCopyAll((Collection<Project>) query.execute());
			return new ArrayList<Project>(c);
		} finally {
			pm.close();
		}
	}

	/**
	 * 得到所有项目
	 * 
	 * @return
	 */
	public List<Project> getPrjs() {
		List<Project> result = new ArrayList<Project>();
		for (int i = 1;; i++) {
			List<Project> prjs = getPrjs(i, 500);
			if (prjs.isEmpty()) {
				break;
			}
			result.addAll(prjs);
		}
		return result;
	}

	/**
	 * 按名称排序得到指定范围内的项目
	 */
	@SuppressWarnings("unchecked")
	public List<Project> getPrjs(long pageIndex, long pageSize) {
		PersistenceManager pm = PMF.get();
		try {
			Query query = pm.newQuery(Project.class);
			query.setOrdering("name");
			query.setRange((pageIndex - 1) * pageSize, pageIndex * pageSize);
			Collection<Project> c = pm.detachCopyAll((Collection<Project>) query.execute());
			return new ArrayList<Project>(c);
		} finally {
			pm.close();
		}
	}

	@SuppressWarnings("unchecked")
	public List<Project> getPrjsBySource(String source, long pageIndex, long pageSize) {
		PersistenceManager pm = PMF.get();
		try {
			Query query = pm.newQuery(Project.class, "source == :source ");
			query.setOrdering("name");
			query.setRange((pageIndex - 1) * pageSize, pageIndex * pageSize);
			Collection<Project> c = pm.detachCopyAll((Collection<Project>) query.execute(source));
			return new ArrayList<Project>(c);
		} finally {
			pm.close();
		}
	}

	@SuppressWarnings("unchecked")
	public List<Project> getPrjsByTag(String role, String tagId, long pageIndex, long pageSize) {
		PersistenceManager pm = PMF.get();
		try {
			Query query = pm.newQuery(Project.class);
			// hidden disabled projects for users and anonymous
			if (role.equals("admin")) {
				query.setFilter("tag == :tagId ");
			} else {
				query.setFilter("tag == :tagId && enabled == true");
			}
			query.setOrdering("name");
			query.setRange((pageIndex - 1) * pageSize, pageIndex * pageSize);
			Collection<Project> c = pm.detachCopyAll((Collection<Project>) query.execute(tagId));
			return new ArrayList<Project>(c);
		} finally {
			pm.close();
		}
	}

	@SuppressWarnings("unchecked")
	public List<Project> getPrjsCachedByTag(String tagId, int pageIndex, int pageSize) {
		PersistenceManager pm = PMF.get();
		try {
			Query query = pm.newQuery(Project.class);
			query.setFilter("tag == :tagId && enabled == true && frozen == false");
			query.setOrdering("name");
			query.setRange((pageIndex - 1) * pageSize, pageIndex * pageSize);
			Collection<Project> c = pm.detachCopyAll((Collection<Project>) query.execute(tagId));
			return new ArrayList<Project>(c);
		} finally {
			pm.close();
		}
	}

	public boolean isExist(String prjId) {
		return get(prjId) != null;
	}

	@SuppressWarnings("unchecked")
	public void normalizePrjsByTag(String tagId) {
		PersistenceManager pm = PMF.get();
		try {
			Query query = pm.newQuery(Project.class);
			query.setFilter("tag == tagId && enabled == false");
			query.setOrdering("name");
			query.setRange(0, 100);
			query.declareParameters("String tagId");
			Collection<Project> c = (Collection<Project>) query.execute(tagId);
			for (Project prj : c) {
				prj.setEnabled(true);
			}
		} finally {
			pm.close();
		}
	}

	public void save(Project prj) {
		PersistenceManager pm = PMF.get();
		try {
			pm.makePersistent(prj);
		} finally {
			pm.close();
		}
	}

	public void update(Project prj) {
		PersistenceManager pm = PMF.get();
		try {
			Project project = pm.getObjectById(Project.class, prj.getId());
			// update id and name if name changed
			if (!prj.getName().equals(project.getName())) {
				project.setName(prj.getName());
			}
			project.setUrl(prj.getUrl());
			project.setDescription(prj.getDescription());
			project.setTag(prj.getTag());
			project.setLabel(prj.getLabel());
			project.setEnabled(prj.getEnabled());
		} finally {
			pm.close();
		}
	}
}
